<?php

/**
 * Theme class
 * Very simple template system and theme loading
 * @version $Id$
 * @copyright 2010
 */

class Theme
{
	public $themes = Array();
	public $themes_path = Array();
	public $theme_name = '';
	public $render = true;

	private $root_path = '';
	private $index = '';
	private $theme_info = '';
	private $index_backup = ''; //for Theme::purge() function
	private $head = ''; //<head> for including JS and CSS and other stuff
	private $assign_array = Array(); //variables for assigning in template
	private $jquery_included = false; //prevent multiple jquery inclusion

	/**
	 * Constructor
	 */
	function __construct($theme = '')
	{
		global $core;

		$this->load_themes();

		if(strlen($theme) > 0) //we want theme
		{
			if(in_array($theme,$this->themes)) //we know it
			{
				$this->set_theme($theme); //set it
			}
			else
			{
				$core->err('Sorry, unknown theme selected!');
			}
		}
		else //use default theme
		{
			$value = mysql_fetch_array(mysql_query("SELECT value FROM ".DB_PREFIX."yaps_config WHERE name = 'default_theme'"));
			$this->set_theme($value['value']);
		}
	}

	/**
	 * Theme::get_root_path()
	 * Geter for root_path
	 * @return
	 */
	public function get_root_path()
	{
		return $this->root_path;
	}

	/**
	 * Theme::get_content()
	 * Useful when developer dont want to echo theme, just get content
	 * @return
	 */
	public function get_content()
	{
		$out = $this->index;

		foreach ($this->assign_array as $name => $value)
		{
			$out = str_ireplace('{'.$name.'}',$value,$out);
		}

		return $out;
	}

	/**
	 * Theme::get_raw_content()
	 * Returns raw, unprocessed content of theme, with no assigns
	 * @return
	 */
	public function get_raw_content()
	{
		return $this->index;
	}

	/**
	 * Theme::set_defaults()
	 * Sets default values for template, if they haven`t been set before by plugin
	 * @return
	 */
	public function set_defaults()
	{
		global $core;

		if(method_exists($core->used_plugin,'rss'))
			$this->add_to_head('<link rel="alternate" type="application/rss+xml" title="{title}" href="rss.php" />');

		//default values
		if(!$this->assign_exists('logo'))	$this->assign('logo',PAGE_NAME);
		if(!$this->assign_exists('underlogo')) $this->assign('underlogo',PAGE_DESC);
		if(!$this->assign_exists('sidebar')) $this->assign('sidebar','');
		if(!$this->assign_exists('footer')) $this->assign('footer','Hi, I am footer:)');
		if(!$this->assign_exists('copyright')) $this->assign('copyright','Powered by Yaps!');
		if(!$this->assign_exists('head')) $this->assign('head', $this->head);
		if(!$this->assign_exists('title')) $this->assign('title',PAGE_NAME);

	}

	public function assign_exists($name)
	{
		return (strlen($this->assign_array[$name]) > 0) ? true : false;
	}

	/**
	 * Theme::generate_menu()
	 * As name suggests, this will generate menu from DB table
	 * @return
	 */
	public function generate_menu()
	{
		$query = mysql_query("SELECT * FROM ".DB_PREFIX."yaps_menu ORDER BY position DESC");
		$out = '<ul>';

		if(mysql_num_rows($query) > 0)
		{
			while($item = mysql_fetch_array($query))
			{
				$out .= '<li><a href="'.$item['link'].'">'.$item['name'].'</a></li>';
			}
		}
		else
		{
			$out .= '<li><a href=".">Home</a></li>';
		}

		$out .= '</ul>';

		$this->assign('menu',$out);
	}

	/**
	 * Theme::set_theme()
	 * This will set theme according to $theme
	 * @param mixed $theme
	 * @return
	 */
	public function set_theme($theme)
	{
		//set up paths
		$this->root_path = $this->themes_path[$theme]['path'];
		$this->index = file_get_contents($this->root_path.'index.html');
		$this->theme_info = $this->themes_path[$theme]['info'];
		$this->theme_name = $theme;

		//and set root_path
		$this->assign('root_path',WEB_URL.$this->root_path);

		//backup index
		$this->index_backup = $this->index;
	}

	/**
	 * Theme::set_theme_file()
	 * Set up theme as a specified file. Usable for blogpost, gallery etc
	 * @param mixed $path
	 * @param mixed $file
	 * @return
	 */
	public function set_theme_file($path = '',$file)
	{
		if(strlen($path) < 1) $path = $this->root_path; //default path to current plugin

		//set up paths
		$this->root_path = $path;
		$this->index = file_get_contents($this->root_path.$file);
		$this->theme_info = 'File: '.$file;

		//and set root_path
		$this->assign('root_path',WEB_URL.$this->root_path);

		//backup index
		$this->index_backup = $this->index;
	}

	/**
	 * Theme::purge()
	 * Purge theme content by loading new one from backup
	 * This file save file_get_contents usage (HD is sooo slow)
	 * @return
	 */
	public function purge()
	{
		$this->index = $this->index_backup;
	}

	/**
	 * Theme::render()
	 * Renders loaded theme
	 * @return
	 */
	public function render()
	{
		global $core;

		if(strlen($this->index) > 0)
		{
			foreach ($this->assign_array as $name => $value)
			{
				$this->index = str_ireplace('{'.$name.'}',$value,$this->index);
			}

			echo $this->index;
		}
		else
		{
			$core->err('You have no theme selected or this theme has corrupted index.html');
		}
	}

	/**
	 * Theme::assign()
	 * Replace template tag {$name} with $value
	 * @param mixed $name
	 * @param mixed $value
	 * @param mixed $append is set to zero, if it is true, than assign will append to assign array instead of replacing the value
	 * @return
	 */
	public function assign($name,$value,$append = 0)
	{
		//$this->index = str_ireplace('{'.$name.'}',$value,$this->index);
		if(!$append)
		{
			$this->assign_array[$name] = $value;
		}
		else
		{
			$this->assign_array[$name] .= $value;
		}
	}

	/**
	 * Theme::load_themes()
	 * Load all themes that we have in themes directory
	 * @return
	 */
	private function load_themes()
	{
		if($handle = opendir(THEMES_DIR)) //lets try to open the themes dir
		{
			while(false !== ($file = readdir($handle)))
			{
				if($file != '.' && $file != '..' && $file != '.svn') //we don`t want this
				{
					$this->themes[] = strtolower($file);
				}
			}

			closedir($handle); //close dir handler

			//loop through themes and read their info
			for($i = 0;$i < sizeof($this->themes);$i++)
			{
				$path = THEMES_DIR.$this->themes[$i].'/';
				$index = $path.'index.html';
				$theme_info = $path.FILE_THEME_INFO;

				//add all paths to array, we will use em later
				$this->themes_path[$this->themes[$i]] = Array(
					'path' => $path,
					'index' => $index,
					'info' => $theme_info);
			}
		}
		else
		{
			$this->err('Can`t open themes directory. Chmod maybe?');
		}
	}

	/**
	 * Theme::add_to_head()
	 * Useful for including javascript libraries and other stuff
	 * @param mixed $what
	 * @return
	 */
	public function add_to_head($what)
	{
		$this->head .= $what;
	}

	/**
	 * Theme::include_jquery()
	 * Include popular javascript framework
	 * @param mixed $css
	 * @return
	 */
	public function include_jquery($css = true)
	{
		if(!$this->jquery_included)
		{
			$this->add_to_head('<script type="text/javascript" src="'.JS_DIR.'jquery-1.4.2.min.js"></script>
			<script type="text/javascript" src="'.JS_DIR.'jquery-ui-1.8.2.custom.min.js"></script>');

			if($css)
			{
				$this->add_to_head('<link type="text/css" href="'.JS_DIR.'ui-lightness/jquery-ui-1.8.2.custom.css" rel="stylesheet" />');
			}

			$this->jquery_included = true;
		}
	}

	/**
	 * Theme::js()
	 * Shortcut for adding javascript
	 * @param mixed $text
	 * @return
	 */
	public function js($text,$jquery_wrapper = true)
	{
		//see if we can add jquery onLoad wrapper
		if($jquery_wrapper)
		{
			$text = '$(function(){'.$text.'});';
		}

		$this->add_to_head('<script type="text/javascript">'.$text.'</script>
		');
	}

	/**
	 * Theme::css()
	 * Shortcut for adding infile css
	 * @param mixed $text
	 * @return
	 */
	public function css($text)
	{
		$this->add_to_head('<style>'.$text.'</style>');
	}

	/**
	 * Theme::include_css()
	 * Shortcut for including CSS from external file
	 * @param mixed $path
	 * @return
	 */
	public function include_css($path)
	{
		$this->add_to_head('<link href="'.$path.'" rel="stylesheet" type="text/css" media="screen" />');
	}

	/**
	 * Theme::include_js()
	 * Shortcut for including JS from external file
	 * @param mixed $path
	 * @return
	 */
	public function include_js($path)
	{
		$this->add_to_head('<script type="text/javascript" src="'.$path.'"></script>');
	}

	/**
	 * Theme::include_validation()
	 * Include validation plugin for jQuery
	 * @return
	 */
	public function include_validation()
	{
		$this->include_jquery();
		$this->add_to_head('<script type="text/javascript" src="'.JS_DIR.'jquery.validate.pack.js"></script>');
	}

	/**
	 * Theme::include_tooltip()
	 * Include tooltip plugin for jQuery
	 * @return
	 */
	public function include_tooltip()
	{
		$this->include_jquery();
		$this->add_to_head('<script type="text/javascript" src="'.JS_DIR.'jquery.tipsy.js"></script>');
		$this->include_css(JS_DIR.'tipsy.css');

		$this->js('$("img[title]").not(".buttons img").tipsy({fade: true});
								$("a[title]").tipsy({fade: true});');
	}

	/**
	 * Theme::icon()
	 * Shortcut for icon from template
	 * @param mixed $name
	 * @param string $alt
	 * @param bool $return
	 * @return
	 */
	public function icon($name,$alt = '',$return = false)
	{
		if($return) return '<img src="images/icons/'.$name.'" alt="'.$alt.'" title="'.$alt.'" class="yaps_icon"/>';
		else echo '<img src="images/icons/',$name,'" alt="',$alt,'" title="',$alt,'" class="yaps_icon"/>';
	}


	/**
	 * Theme::set_title()
	 * Shortcut for webpage title
	 * @param mixed $title
	 * @return
	 */
	public function set_title($title)
	{
		$this->assign('title',PAGE_NAME.' - '.$title);
	}

	/**
	 * Theme::do_other_plugins_stuff()
	 * Do other plugins things, like display twitter plugin, etc.
	 * @return
	 */
	public function do_other_plugins_stuff()
	{
		global $core;

		include $this->theme_info;

		if($twitter == true && $core->is_plugin('twitter')) //does this theme supports twitter?
		{
			$plugin = $core->load_plugin('twitter');
			$plugin->display_tweets();
		}

		if($core->is_plugin('sidebar')) //do we have sidebar plugin?
		{
			$plugin = $core->load_plugin('sidebar');
			$plugin->generate_sidebar();
		}
	}

	/**
	 * Theme::get_theme_list()
	 * Just for better reading of code
	 * @return
	 */
	public function get_theme_list()
	{
		return $this->themes;
	}

	public function link($text,$plugin,$action = '',$id = '',$seo_stuff = '')
	{
		global $core;

		if($action) $rest_of_it .= '-'.$action;
		if($id) $rest_of_it .= '-'.$id;
		if($seo_stuff) $rest_of_it .= '-'.$core->encode_url($seo_stuff);

		return '<a href="'.WEB_URL.$plugin.$rest_of_it.'" id="'.$plugin.'_'.$action.'">'.$text.'</a>';
	}

	/**
	 * Theme::button()
	 * Create nice button :)
	 * @param mixed $text Text on button
	 * @param mixed $link
	 * @param string $image Standard Yaps! icon
	 * @param string $class What class should we add to link?
	 * @param mixed $return Should we return(true) or echo(false). Defaul is echo
	 * @return
	 */
	public function button($text,$link,$image = '',$class = '', $return = false)
	{
		$link_string = '<a href="'.$link.'" class="buttons '.$class.'">'.(($image) ? $this->icon($image,$text,true) : '').$text.'</a>';

		if($return) return $link_string;
		echo $link_string;
	}

	/**
	 * Theme::back_button()
	 * Go back in history with no JS
	 * @param string $text
	 * @return
	 */
	public function back_button($text = 'Zpět')
	{
		global $core;
		echo '<br />';
		$this->button($text,$core->load_last_page(),'arrow_left.png');
	}

	/**
	 * Theme::yesno()
	 * Create simple yes/no dialog
	 * @param mixed $answer Text of answer
	 * @param mixed $yes_link Where to redirect if YES
	 * @param mixed $no_link Where to redirect if NO
	 * @param string $yes_text Yes button text
	 * @param string $no_msg No button text
	 * @return
	 */
	public function yesno($answer,$yes_link,$no_link,$yes_text = 'Yes',$no_text = 'No')
	{
		echo '<div><div class="yesno_answer">',$answer,'</div>';
		$this->button($yes_text,$yes_link,'accept.png','positive');
		$this->button($no_text,$no_link,'cross.png','negative');
		echo '</div>';
	}
}

?>